package com.xiaoqiudong.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaoqiudong.mapper.UserInfoMapper;
import com.xiaoqiudong.pojo.User;
import com.xiaoqiudong.pojo.game.OnlineUserManager;
import com.xiaoqiudong.pojo.game.Room;
import com.xiaoqiudong.pojo.game.RoomManager;
import com.xiaoqiudong.pojo.response.GameReadyResponse;
import com.xiaoqiudong.pojo.response.GameResponse;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA
 * Descroption
 * User:dell
 * Date:2025-08-16
 * Time:20:35
 */
@Component
public class GameAPI extends TextWebSocketHandler {
    @Resource
    private UserInfoMapper userInfoMapper;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RoomManager roomManager;
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //获取用户信息
        User user = (User) session.getAttributes().get("user");
        GameReadyResponse response = new GameReadyResponse();
        if(user == null){
            response.setOk(false);
            response.setReason("用户未登录");
            String json = objectMapper.writeValueAsString(response);
            session.sendMessage(new TextMessage(json));
            return;
        }
        //判定用户是否进入房间
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room == null){
            response.setOk(false);
            response.setReason("用户尚未匹配到");
            String json = objectMapper.writeValueAsString(response);
            session.sendMessage(new TextMessage(json));
            return;
        }
        //判定用户是否多开 (该用户是不是已经在其他地方进入游戏了)
        if(onlineUserManager.getGameHall(user.getUserId()) != null
                ||onlineUserManager.getFromGameRoom(user.getUserId()) != null){
            response.setReason("禁止用户多开");
            response.setOk(true);
            response.setMessage("repeatConnection");
            String json = objectMapper.writeValueAsString(response);
            session.sendMessage(new TextMessage(json));
        }
        //设置玩家上线
        onlineUserManager.enterGameRoom(user.getUserId(), session);
        //把玩家加入游戏房间
        synchronized (room){
            if (room.getUser1() == null){
                room.setUser1(user);
                room.setWhiteUser(user.getUserId());
                System.out.println("玩家"+user.getUsername()+"准备就绪，作为玩家1");
                return;
            }
            if (room.getUser2() == null) {
                room.setUser2(user);
                System.out.println("玩家" + user.getUsername() + "准备就绪，作为玩家2");

                //通知玩家双方已经就绪
                //通知玩家1
                noticeGameReady(room, room.getUser1(), room.getUser2());
                //通知玩家2
                noticeGameReady(room, room.getUser2(), room.getUser1());
                return;
            }
        }
        //此处如果又有玩家尝试连接同一个房间, 就提示报错
        response.setOk(false);
        response.setReason("当前房间已满，你不能进入房间");
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));

    }

    private void noticeGameReady(Room room, User thisUser, User thatUser) throws IOException {
        GameReadyResponse gameReadyResponse = new GameReadyResponse();
        gameReadyResponse.setOk(true);
        gameReadyResponse.setMessage("gameReady");
        gameReadyResponse.setReason("");
        gameReadyResponse.setRoomId(room.getRoomId());
        gameReadyResponse.setThisUserId(thisUser.getUserId());
        gameReadyResponse.setThatUserId(thatUser.getUserId());
        gameReadyResponse.setWhiteUser(room.getWhiteUser());
        WebSocketSession webSocketSession = onlineUserManager.getFromGameRoom(thisUser.getUserId());
        webSocketSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameReadyResponse)));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //拿到用户的信息
        User user = (User) session.getAttributes().get("user");
        if (user == null){
            System.out.println("[ handleTextMessage]:当前玩家尚未登录" );
            return;
        }
        //根据用户id 获取房间对象
        Room room = roomManager.getRoomByUserId(user.getUserId());
        room.putChess(message.getPayload());

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null){
            return;
        }
        WebSocketSession tmpSession = onlineUserManager.getFromGameRoom(user.getUserId());
        if (tmpSession == session){
            //避免用户多开的情况，第二个用户退出连接动作, 导致第一个用户的会话被删除
            onlineUserManager.exitGameRoom(user.getUserId());
        }
        System.out.println("玩家："+user.getUsername()+"游戏房间连接异常");
        noticeThatUserWin(user);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null){
            System.out.println("玩家离线");
            return;
        }
        WebSocketSession tmpSession = onlineUserManager.getFromGameRoom(user.getUserId());
        if (tmpSession == session){
            System.out.println("玩家"+user.getUsername()+"离开房间");
            onlineUserManager.exitGameRoom(user.getUserId());
        }
        noticeThatUserWin(user);
    }
    private void noticeThatUserWin(User user) throws IOException {
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if (room == null){
            System.out.println("房间已经释放，无需通知对手");
            return;
        }
        //在房间里里面找到对手
        User thatUser = (user == room.getUser1() ? room.getUser2():room.getUser1());

        //找到对手的在线状态
        WebSocketSession webSocketSession = onlineUserManager.getFromGameRoom(thatUser.getUserId());
        if (webSocketSession == null){
            //对手也掉线
            System.out.println("对手也掉线，无需通知");
            return;
        }
        //通知对手，
        GameResponse response = new GameResponse();
        response.setMessage("putChess");
        response.setUserId(thatUser.getUserId());
        response.setWinner(thatUser.getUserId());
        webSocketSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        //更新玩家分数
        int winUserId = thatUser.getUserId();
        int loseUserId = user.getUserId();
        userInfoMapper.userWin(winUserId);
        userInfoMapper.userLose(loseUserId);


        //释放房间
        roomManager.remove(room.getRoomId(), room.getUser1().getUserId(),room.getUser2().getUserId());
    }
}
